var image_selection_lists = $A();

var AjaxEditForm = Class.create({
	initialize: function( container_options, options){
		container_options = Object.extend({
			attributes: {},
			style: {}
		}, container_options || {});
		this.container_options = Object.extend({
			
		}, container_options.attributes || {});
		this.container_style = Object.extend({
			position: 'absolute',
			background: 'white',
			width: '80%'
		}, container_options.style || {});
		this.options = Object.extend({
			
		}, options || {});
		this.container = new Element('div', this.container_options);
		this.container.setStyle(this.container_style);
		this.container.identify();
		$$('body')[0].insert(this.container);
	},
	create: function( trigger, url){
		this.trigger = trigger;
		this.container.hide();
		new Ajax.Request(url, {
			onComplete: function(r){
				this.container.update(r.responseText);
				this.prepareEditForm.bind(this).defer();
			}.bind(this)
		});
	},
	prepareEditForm: function(){
		initializeFormControls(this.container);
		this.form = this.container.down('form');
		var f = this.form;
		if( f ){
			var s = f.select('input[type=submit]');
			s.invoke('observe', 'click', this.submit.bindAsEventListener(this));
			this.container.show();
		}
	},
	submit: function(e){
		e.stop();
		var elm = e.element();
		var cancel = (elm.value.toLowerCase() == 'cancel');
		var f = this.form;
		f.select('textarea.rte').each(function(t){
			try{
				FCKeditorAPI.GetInstance(t.identify()).UpdateLinkedField();
			}catch(e){} 
		});
		var values = f.serialize();
		values += '&ajax=1';
		if( cancel ) values += '&cancel=1';
		f.disable();
		new Ajax.Request( f.action, {
			'method': f.method,
			'parameters': values,
			'onComplete': function(r){
				if( cancel ){
					this.close(null);
					return;
				}
				var success = r.responseText.split('::')[0] || null;
				var json = eval('(' + (r.responseText.split('::')[1] || '{}') + ')');
				if( cancel || success == '1'){
					this.close(json);
				}else{
					this.container.hide();
					this.container.update(r.responseText);
					this.prepareEditForm.bind(this).defer();
				}
			}.bind(this)
		});
	},
	observe: function(){
		this.container.observe.apply(this.container, arguments);
	},
	close: function(json){
		new Effect.Fade(this.container);
		this.container.fire('ajaxedit:complete', {result: json});
	}
});

/* TODO
 * still have to have fckinit run for rich text editor in ajax box
 * need to populate hidden field with description ids if this is a new project
 */
var Descriptions = {
	created: false,
	description_ids: [],
	create: function(elm, item_id){
		if (!this.created) {
			this.created = true;
			this.elm = $(elm);
			this.item_id = item_id;
			this.options = Object.extend({
				insertion_element: null,
				input_element: 'new_descriptions_input',
				title: '<h3>Descriptions</h3>'
			}, arguments[2] || {});
			if (!this.elm || this.elm.tagName.toLowerCase() != 'select') 
				return;
			this.edit_form = new AjaxEditForm();
			this.option_elms = this.elm.select('option');
			this.links = [];
			
			var temp = $(this.options.insertion_element) || this.elm;
			var ul = new Element('ul', {
				'class': 'description_elements'
			});
			var li = []
			if (!item_id) {
				this.input_elm = $(this.options.input_element);
				if (this.input_elm) {
					/* want to parse the value attribute and create description_ids based on the options */
					var pieces = this.input_elm.readAttribute('value').split(',');
					var l = pieces.length;
					for( var i=0; i<l; i++){
						var t = pieces[i].split(':');
						if( t.length == 2 ){
							this.description_ids[t[1]] = t[0];
						}
					}
				}
				else {
					var input_element = this.options.input_element;
					this.input_elm = new Element('input', {
						type: 'hidden',
						name: input_element,
						id: input_element
					});
					temp.insert({
						after: this.input_elm
					});
				}
			}
			this.option_elms.each(function(o){
				var href = getBasePath() + '/cmf/descriptions/' + (this.description_ids[o.value]?'editajax/' + this.description_ids[o.value]:'editbycategoryandproject/' + o.value + '/' + item_id);
				this.links[o.value] = new Element('a', {
					href: href
				}).update('Edit ' + o.text + ' description.');
				var a = this.links[o.value];
				this.links[o.value].observe('click', function(e){
					e.stop();
					this.edit_form.create(a, a.readAttribute('href'));
				}.bind(this));
				ul.insert(new Element('li').insert(this.links[o.value]));
			}, this);
			temp.insert({
				after: ul
			});
			temp.insert({
				after: this.options.title
			});
			this.edit_form.observe('ajaxedit:complete', this.complete.bindAsEventListener(this));
		}
	},
	complete: function(e){
		if( this.input_elm && e.memo.result){
			if( this.input_elm.value ) this.input_elm.value += ',';
			this.input_elm.value += e.memo.result.id + ':' + e.memo.result.category_id;
			this.links[e.memo.result.category_id].writeAttribute('href', getBasePath() + '/cmf/descriptions/editajax/' + e.memo.result.id);
		}
	}
};

var SelectMaster = Class.create({
	initialize: function(elm){
		this.elm = $(elm);
		if( !this.elm || this.elm.tagName.toLowerCase() != 'select') return null;
		this.id = this.elm.identify();
		this.slaves = $$('.' + this.id + '_select_slave');
		this.elm.observe('click', this.adjustSlaves.bind(this));
		this.adjustSlaves();
	},
	
	adjustSlaves: function(e){
		var options = this.elm.select('option');
		var selected = options.map(function(o){
			return (o.selected && o.value) || null;
		}).compact();
		var l = this.slaves.length;
		for( var i=0; i<l; i++){
			this._adjustSlave(this.slaves[i], selected);
		}
	},
	
	_adjustSlave: function( slave, selected){
		var options = slave.select('option');
		var shown = 0;
		options.each(function(o){
			if( selected.indexOf(o.value) === -1 ){
				o.hide();
				o.selected = false;
			}else{
				++shown;
				o.show();
			}
		});
		/* throw an empty option in if there are no options on a non-multiple select, otherwise 
		 * user will see the first option.
		 */
		if( !slave.readAttribute('multiple')){
			if (!shown) {
				var d = new Element('option', {
					id: slave.identify() + '_default',
					value: '',
					selected: 'selected'
				}).update('');
				d.selected = true;
				slave.insert(d);
			}else{
				try {
					slave.down('#' + slave.identify() + '_default').remove();
				}catch(e){}
			}
		}
	}
});

/*
 * TODO: change all upload initializers to use new function with callback
 * TODO: put all of this in an anonymous function
 */

function processFormRelatedItem(e, original){
	var edit = e.down('a.form_related_item_edit_link');
	var del = e.down('a.form_related_item_delete_link');
	if( !original ){
		var id = e.childElements().find(function(e){ return e.readAttribute('id');}).identify();
		original = '<input type="hidden" name="' + id + '" id="' + id + '" />';
	}
	if( edit ){
		edit.observe('click', function(evt){
			evt.stop();
			createEditForm(null, edit, null, edit.readAttribute('href'));
		});
	}
	if( del ){
		del.observe('click', function(evt){
			evt.stop();
			/* need to replace this element with the old placeholder so uploading after a delete will work correctly */
			if (original) {
				e.replace(original);
			}
			else {
				e.remove();
			}
			new Ajax.Request(del.readAttribute('href') + '/1', {
				method: 'post'
			});
		});
	}
}

function initializeFormControls(elm){
	var f = $$;
	elm = $(elm);
	if( elm ){
		f = Element.select.curry(elm);
	}
	
	f('.drawer').each( function(e){
		new PSWrap.Animation.OpenCloseIDBound(e, {
			duration: 0.75,
			transition: Effect.Transitions.sinoidal
		});
	});
	
	f('.select_master').each(function(e){
		new SelectMaster(e);
	});
	
	var id = f('input[name*=id]')[0];
	if( id ) id = id.value;
	Descriptions.create(f('#related_categories')[0], id);
	
	f('select[class^=dynamic_add]').each(function(e){
		var params = {
			value: 'id',
			text: 'text',
			link_text: 'Add New'
		};
		var select = e;
		var temp = e.className.match(/dynamic_add:([^\s]+)/);
		var pieces = temp[1].split('::');
		temp = pieces.shift();
		pieces.each(function(p){
			var f_v = p.split(':');
			params[f_v[0]] = f_v[1];
		});
		temp = getBasePath() + '/cmf/' + temp + '/editajax/';
		var link = new Element('a', {href: temp}).update(params.link_text);
		link.observe('click', function(e){
			e.stop();
			var elm = e.element();
			createEditForm(null, elm, null, temp, function(r){
				var json = r.split('::');
				json = eval('(' + json[1] + ')');
				var opt = new Element('option', {value: json[params.value]}).update(json[params.text]);
				select.insert({
					top: opt
				});
				opt.selected = 'selected';
			});
		});
		e.insert({after: link});
	});
	
	f('.form_related_item').each( function(e){
		processFormRelatedItem(e);
	});
	
	f('textarea.rte').each( initializeFCKEditor );
	
	f('.project_remove_featured').each( function(a){
		a.observe('click', function(evt){
			evt.stop();
			var p = a.up('p');
			if( p ) p.hide();
			var proj = this.innerHTML;
			new Ajax.Request( this.readAttribute('href'), {
				method: 'get',
				onSuccess: function(r){
					p.insert({'after': '<p>' + proj + ' is no longer featured.</p>'});
					p.remove();
				},
				onFailure: function(r){
					p.insert({'after': '<p>' + proj + ' could not be removed. Please try again. ' + r.statusText + ', ' + r.status + '</p>'});
					p.show();
				}
			});
		}.bind(a));
		a.show();
	});
	
	// initialize calendar elements
	f('input.calendar').each( function(i){
		if( i.readAttribute('id')){
			var id = i.readAttribute('id');
			var btn = new Element('button', {type: 'button', id: id + '_action_open'});
			btn.update('select');
			var cdiv = new Element('div', {id: id + '_calendar', 'class': 'scal', style: 'display: none; position: absolute;'});
			
			i.insert({after: btn});
			btn.insert({after: cdiv});
			Position.clone( btn, cdiv, { setWidth: false, setHeight: false, offsetTop: btn.getHeight() + 2});
			
			var sc = new scal(cdiv, i, {noEffect: true});
			
			btn.observe('click', function(){
				if( i.value && i.value != '0000-00-00'){
					var dvs = i.value.split('-');
					var year = parseInt(dvs[0]);
					var month = parseInt(dvs[1]) - 1;
					var day = parseInt(dvs[2]);
					var d = new Date( year, month, day);
					d = isNaN(d)?new Date():d;
					sc.setCurrentDate(d);
				}
				sc.toggleCalendar();
			});
		}
	});
	
	f('input.image_list_ajax_upload').each(function(i){
		i = $(i);
		if( i ){
			var action = i.readAttribute('value');
			action = action?action:i.readAttribute('title');
			action = action?action:getBasePath() + '/cmf/fileupload/doupload/';
			var u = new PSWrap.AjaxUpload(i, {
				action: action,
				onComplete: function(msg, elm){
					ajaxUploadOnComplete(msg, elm, function(r, elm){
						var id = elm.identify();
						var last_index = id.lastIndexOf('_');
						last_index = last_index == -1?id.length:last_index;
						var il_id = id.substr( 0, last_index);
						var il = PSWrap.FormControls.SingleContainerMultiselects.get(il_id);
						if( il ){
							il.addOption(r[2], r[1], true);
						}	
					});
				}
			});
			if (u) {
				i.observe('change', u.submit.bind(u));
			}
		}
	});
	var container_template = new Template('<ul class="image_list" id="#{id}"></ul>');
	var item_template = new Template('<li#{css_class} id="#{id}"><img src="#{text}" alt="#{text}" /></li>');
	f('select.image_list').each(function(s){
		var limit = 5;
		function doSortable(list){
			Sortable.create( list.identify(), {
				overlap: 'horizontal',
				tag: 'li',
				constraint: null,
				onUpdate: serializeSortableToInput
			});
			serializeSortableToInput(list);
		}
		function toggleUpload(id, t){
			var input = $(id);
			if (input) {
				if (t) {
					input.disable();
					if (!this.note) {
						this.note = new Element('p').update('You have reached the maximum number of uploads, please delete an image to upload another.')
						input.insert({
							before: this.note
						});
					}
					this.note.show();
				}
				else {
					input.enable();
					if (this.note) {
						this.note.hide();
					}
				}
			}
		}
		new PSWrap.FormControls.SingleContainerMultiselect( s, container_template, item_template);
		if(limit && s.select('li').length >= limit){
			toggleUpload(s.identify() + '_upload', true);
		}
		var view_link = new Element('a', {href: '#', target: '_blank', 'class': 'image_list_detail_link', title: 'View Image Details'}).update('<span>View Image Details</span>');
		view_link.observe('click', function(e){
			if( view_link.readAttribute('href') == '#' ){
				e.stop();
				return false;
			}
		});
		s.observe('pswrap:optionadded', function(e){
			var element = e.memo.element;
			var list = e.memo.container;
			if( limit && list.select('li').length >= limit ){
				toggleUpload( s.identify() + '_upload', true);
			}
			element.observe('click', function(e){
				list.select('li').invoke('removeClassName', 'click_selected');
				element.addClassName('click_selected');
				var id = element.identify().split('_').last();
				view_link.setAttribute('href', ApplicationPaths.basepath + '/cmf/artistimages/detail/' + id);
			});
			doSortable(list);
		});
		s.observe('pswrap:optionremoved', function(e){
			if( limit && e.memo.container.select('li').length <= limit){
				toggleUpload( s.identify() + '_upload', false);
			}
			e.memo.element.stopObserving();
			doSortable(e.memo.container);
		});
		s.next().insert({after: view_link});
		
		var edit_link = new Element('a', {href: '#', 'class': 'image_list_edit_link', title: 'Edit Selected Image Info'}).update('<span>Edit Select Image Info</span>');
		edit_link.observe('click', function(e){
			e.stop();
			var element = s.next().down('li.click_selected');
			if( element ){
				var value = element.identify().split('_').last();
				if( value ){
					createEditForm(null, edit_link, null, ApplicationPaths.basepath + '/cmf/artistimages/editajax/' + value );
				}
			}
		});
		view_link.insert({after: edit_link});
		var del_link = new Element('a', {href: '#', 'class': 'image_list_delete_link', title: 'Delete Selected Image'}).update('<span>Delete Selected Image</span>');
		del_link.observe('click', function(e){
			e.stop();
			var element = s.next().down('li.click_selected');
			if( element ){
				var value = element.identify().split('_').last();
				if (value && confirm('Are you sure you want to delete this image?')) {
					new Ajax.Request(ApplicationPaths.basepath + '/cmf/artistimages/delete/' + value + '/1', {method: 'post'});
	 				PSWrap.FormControls.SingleContainerMultiselects.items().invoke('removeOption', value);
				}
			}
		});
		edit_link.insert({after: del_link});
	});
	
	container_template = new Template('<ul class="document_list" id="#{id}"></ul>');
	item_template = new Template('<li#{css_class} id="#{id}"><input type="checkbox" id="#{id}_checkbox" /> <a href="#{text}" target="_blank">#{text}</a> <a class="edit" href="/cmf/documents/editajax/#{value}">edit</a> <a class="delete" href="/cmf/documents/delete/#{value}/1">delete</a></li>');
	f('.document_list').each( function(d){
		new PSWrap.FormControls.SingleContainerMultiselect( d, container_template, item_template, {select_element: 'input[type=checkbox]', select_event: 'click', deselect_event: 'click'});
		d.observe('pswrap:optionadded', function(e){
			//console.log('optionadded!');
			//console.log(e.memo);
			var option = e.memo.option.option;
			var element = e.memo.element;
			if( option.selected ){
				var checkbox = element.identify() + '_checkbox';
				checkbox = $(checkbox);
				if( checkbox ){
					checkbox.checked = true;
				}
			}
			element.select('a.edit').each( function(e){
				var href = e.readAttribute('href');
				if( href ){
					e.observe('click', function(evt){
						try{
							evt.stop();
						}catch(ex){}
						createEditForm(null, e, null, href);
					});
				}
			});
			element.select('a.delete').invoke('observe', 'click', function(e){
				try{
					e.stop();
				}catch(ex){}
				deleteDocument(option.value);
			});
		});
	});
	
	var element_template = new Template('<img src="#{text}" alt="#{id}" id="#{id}" />');
	f('.image_selection_list').each( function(i){
		var max_selected = i.readAttribute('max_selected') || 0;
		image_selection_lists.push(new PSWrap.FormControls.DragDropMultiselect( i, element_template, {
			onInit: [createImageListSortableInit, createEditDeleteBuckets],
			onSelectedChange: createImageListSortable,
			onOptionChange: toggleEditDeleteBuckets,
			options_title: 'Options',
			selected_title: 'Currently Selected (Double Click to Remove)',
			max_selected: max_selected
		}));
	});
	
	f('input.single_document_ajax_upload_editable').each( function(i){
		i = $(i);
		if( i ){
			var action = i.readAttribute('value');
			action = action?action:i.readAttribute('title');
			action = action?action:getBasePath() + '/cmf/fileupload/doupload/';
			var u = new PSWrap.AjaxUpload(i, {
				action: action,
				onComplete: function(msg, elm){
					//console.log(msg);
					if (msg.indexOf(':') != -1) {
						var r = msg.split(':');
						var response_code = parseInt(r[0]);
						var msg_id = elm.identify() + '_message';
						var msg = $(msg_id);
						if ( response_code != 0) {
							if( msg ){
								msg.hide();
							}
							var id = elm.identify();
							if( response_code == 2){
								// need to create a hidden input to keep track of the image ids to insert into the relational table at save time
								var hidden_input_id = 'new_' + id;
								var hidden_input = $(hidden_input_id);
								if( !hidden_input ){
									hidden_input = new Element('input', {type: 'hidden', name: hidden_input_id, id: hidden_input_id, value: r[1] + '=>' + r[2]});
									elm.insert({
										before: hidden_input
									});
								}else{
									hidden_input.value = hidden_input.value + ';' + r[1] + '=>' + r[2];
								}
							}
							var last_index = id.lastIndexOf('_');
							last_index = last_index == -1?id.length:last_index;
							var link_id = id.substr( 0, last_index);
							var link = $(link_id);
							if( link ){
								if( link.tagName != 'A'){
									var attr = {};
									var l = link.attributes.length;
									for( i=0; i<l; i++){
										if( link.attributes[i].name != 'type'){
											attr[link.attributes[i].name] = link.attributes[i].value; 
										}
									}
									attr['target'] = '_blank';
									var nlink = new Element('a', attr);
									link.replace(nlink);
									link = nlink;
								}
								var link_text = r[2].substr( r[2].lastIndexOf('/'), r[2].length);
								link.update(r[2]);
								link.href = r[2];
								
								var edit_link = new Element('a', {
									'class': 'document_edit_link',
									'id': 'document_edit_' + r[1],
									'href': getBasePath() + '/cmf/documents/editajax/' + r[1]
								});
								edit_link.update('edit document');
								edit_link.observe('click', function(e){
									try{
										e.stop();
									}catch(ex){}
									createEditForm(null, edit_link, null, getBasePath() + '/cmf/documents/editajax/' + r[1]);
								});
								link.insert({'after': ' '});
								link.insert({'after': edit_link});
							}
							elm.clear();
						}else{
							if( !msg ){
								msg = new Element('div', {'class': 'upload_error_message', 'id': msg_id, 'onclick': '$(this).remove();'});
								elm.insert({before: msg});
							}
							msg.update(r[1]);
							msg.show();
						}
					}
				}
			});
			if (u) {
				i.observe('change', u.submit.bind(u));
			}
		}
	});
	
	f('input.single_document_ajax_upload').each( function(i){
		i = $(i);
		if( i ){
			var action = i.readAttribute('value');
			action = action?action:i.readAttribute('title');
			action = action?action:getBasePath() + '/cmf/fileupload/doupload/';
			var u = new PSWrap.AjaxUpload(i, {
				action: action,
				onComplete: function(msg, elm){
					//console.log(msg);
					if (msg.indexOf(':') != -1) {
						var r = msg.split(':');
						var response_code = parseInt(r[0]);
						var msg_id = elm.identify() + '_message';
						var msg = $(msg_id);
						if ( response_code != 0) {
							if( msg ){
								msg.hide();
							}
							var id = elm.identify();
							if( response_code == 2){
								// need to create a hidden input to keep track of the image ids to insert into the relational table at save time
								var hidden_input_id = 'new_' + id;
								var hidden_input = $(hidden_input_id);
								if( !hidden_input ){
									hidden_input = new Element('input', {type: 'hidden', name: hidden_input_id, id: hidden_input_id, value: r[1] + '=>' + r[2]});
									elm.insert({
										before: hidden_input
									});
								}else{
									hidden_input.value = hidden_input.value + ';' + r[1] + '=>' + r[2];
								}
							}
							var last_index = id.lastIndexOf('_');
							last_index = last_index == -1?id.length:last_index;
							var link_id = id.substr( 0, last_index);
							var link = $(link_id);
							if( link ){
								if( link.tagName != 'A'){
									var attr = {};
									var l = link.attributes.length;
									for( i=0; i<l; i++){
										if( link.attributes[i].name != 'type'){
											attr[link.attributes[i].name] = link.attributes[i].value; 
										}
									}
									attr['target'] = '_blank';
									var nlink = new Element('a', attr);
									link.replace(nlink);
									link = nlink;
								}
								var link_text = r[2].substr( r[2].lastIndexOf('/'), r[2].length);
								link.update(r[2]);
								link.href = r[2];
							}
							elm.clear();
						}else{
							if( !msg ){
								msg = new Element('div', {'class': 'upload_error_message', 'id': msg_id, 'onclick': '$(this).remove();'});
								elm.insert({before: msg});
							}
							msg.update(r[1]);
							msg.show();
						}
					}
				}
			});
			if (u) {
				i.observe('change', u.submit.bind(u));
			}
		}
	});

	f('input.single_image_ajax_upload').each( function(i){
		i = $(i);
		if( i ){
			var action = i.readAttribute('value');
			action = action?action:i.readAttribute('title');
			action = action?action:getBasePath() + '/cmf/fileupload/doupload/';
			var u = new PSWrap.AjaxUpload(i, {
				action: action,
				onComplete: function(msg, elm){
					//console.log(msg);
					if (msg.indexOf(':') != -1) {
						var r = msg.split(':');
						var response_code = parseInt(r[0]);
						var msg_id = elm.identify() + '_message';
						var msg = $(msg_id);
						if ( response_code != 0) {
							if( msg ){
								msg.hide();
							}
							var id = elm.identify();
							if( response_code == 2){
								// need to create a hidden input to keep track of the image ids to insert into the relational table at save time
								var hidden_input_id = 'new_' + id;
								var hidden_input = $(hidden_input_id);
								if( !hidden_input ){
									hidden_input = new Element('input', {type: 'hidden', name: hidden_input_id, id: hidden_input_id, value: r[1] + '=>' + r[2]});
									elm.insert({
										before: hidden_input
									});
								}else{
									hidden_input.value = hidden_input.value + ';' + r[1] + '=>' + r[2];
								}
							}
							var last_index = id.lastIndexOf('_');
							last_index = last_index == -1?id.length:last_index;
							var img_id = id.substr( 0, last_index);
							var img = $(img_id);
							if( img ){
								//console.log(img.tagName);
								if( img.tagName != 'IMG'){
									//console.log('creating image!');
									var attr = {};
									var l = img.attributes.length;
									for( i=0; i<l; i++){
										//console.log(i + ': ' + img.attributes[i].name + ' = ' + img.attributes[i].value);
										if( img.attributes[i].name != 'type'){
											attr[img.attributes[i].name] = img.attributes[i].value; 
										}
									}
									var nimg = new Element('img', attr);
									//console.log('created image');
									img.replace(nimg);
									img = nimg;
								}
								img.src = r[2];
							}
							elm.clear();
						}else{
							if( !msg ){
								msg = new Element('div', {'class': 'upload_error_message', 'id': msg_id, 'onclick': '$(this).remove();'});
								elm.insert({before: msg});
							}
							msg.update(r[1]);
							msg.show();
						}
					}
				}
			});
			if (u) {
				i.observe('change', u.submit.bind(u));
			}
		}
	});
	
	f('input.image_bucket_ajax_upload').each( function(i){
		i = $(i);
		if (i) {
			var action = i.readAttribute('value');
			action = action?action:i.readAttribute('title');
			action = action?action:getBasePath() + '/cmf/fileupload/doupload/';
			//console.log('ajax upload: ' + i + ', action: ' + action);
			var u = new PSWrap.AjaxUpload(i, {
				action: action,
				onComplete: function(msg, elm){
					//console.log(msg);
					if (msg.indexOf(':') != -1) {
						var r = msg.split(':');
						var response_code = parseInt(r[0]);
						var msg_id = elm.identify() + '_message';
						var msg = $(msg_id);
						if ( response_code != 0) {
							if( msg ){
								msg.hide();
							}
							var id = elm.identify();
							if( response_code == 2){
								// need to create a hidden input to keep track of the image ids to insert into the relational table at save time
								var hidden_input_id = 'new_' + id;
								var hidden_input = $(hidden_input_id);
								if( !hidden_input ){
									hidden_input = new Element('input', {type: 'hidden', name: hidden_input_id, id: hidden_input_id, value: r[1] + '=>' + r[2]});
									elm.insert({
										before: hidden_input
									});
								}else{
									hidden_input.value = hidden_input.value + ';' + r[1] + '=>' + r[2];
								}
							}
							var last_index = id.lastIndexOf('_');
							last_index = last_index == -1?id.length:last_index;
							var isl_id = id.substr( 0, last_index);
							var isl = PSWrap.FormControls.DragDropMultiselects.get(isl_id);
							//console.log('got isl: ' + isl);
							isl.addElement(r[1], r[2]);
							elm.clear();
						}else{
							if( !msg ){
								msg = new Element('div', {'class': 'upload_error_message', 'id': msg_id, 'onclick': '$(this).remove();'});
								elm.insert({before: msg});
							}
							msg.update(r[1]);
							msg.show();
						}
					}
				}
			});
			if (u) {
				i.observe('change', u.submit.bind(u));
			}
		}
	});
	
	f('input.document_list_ajax_upload').each( function(i){
		i = $(i);
		if (i) {
			var action = i.readAttribute('value');
			action = action?action:i.readAttribute('title');
			action = action?action:getBasePath() + '/cmf/fileupload/doupload/';
			//console.log('ajax upload: ' + i + ', action: ' + action);
			var u = new PSWrap.AjaxUpload(i, {
				action: action,
				onComplete: function(msg, elm){
					//console.log(msg);
					if (msg.indexOf(':') != -1) {
						var r = msg.split(':');
						var response_code = parseInt(r[0]);
						var msg_id = elm.identify() + '_message';
						var msg = $(msg_id);
						if ( response_code != 0) {
							if( msg ){
								msg.hide();
							}
							var id = elm.identify();
							if( response_code == 2){
								// need to create a hidden input to keep track of the image ids to insert into the relational table at save time
								var hidden_input_id = 'new_' + id;
								var hidden_input = $(hidden_input_id);
								if( !hidden_input ){
									hidden_input = new Element('input', {type: 'hidden', name: hidden_input_id, id: hidden_input_id, value: r[1] + '=>' + r[2]});
									elm.insert({
										before: hidden_input
									});
								}else{
									hidden_input.value = hidden_input.value + ';' + r[1] + '=>' + r[2];
								}
							}
							var last_index = id.lastIndexOf('_');
							last_index = last_index == -1?id.length:last_index;
							var isl_id = id.substr( 0, last_index);
							//console.log('looking for id: ' + isl_id);
							var isl = PSWrap.FormControls.SingleContainerMultiselects.get(isl_id);
							//console.log('got isl: ' + isl);
							if( isl ){
								//console.log('adding Option: ' + r[2] + ', ' + r[1]);
								isl.addOption( r[2], r[1], 1);
							}
							elm.clear();
						}else{
							if( !msg ){
								msg = new Element('div', {'class': 'upload_error_message', 'id': msg_id, 'onclick': '$(this).remove();'});
								elm.insert({before: msg});
							}
							msg.update(r[1]);
							msg.show();
						}
					}
				}
			});
			if (u) {
				i.observe('change', u.submit.bind(u));
			}
		}
	});
	
	f('.edit_ajax_link').each(function(e){
		var href = e.readAttribute('href');
		if( href ){
			e.observe('click', function(evt){
				try{
					evt.stop();
				}catch(ex){}
				createEditForm(null, e, null, href);
			});
		}
	});

	f('input.single_video_ajax_upload').each( function(i){
		i = $(i);
		if( i ){
			var action = i.readAttribute('value');
			action = action?action:i.readAttribute('title');
			action = action?action:getBasePath() + '/cmf/fileupload/doupload/';
			var u = new PSWrap.AjaxUpload(i, {
				action: action,
				onComplete: function(msg, elm){
					ajaxUploadOnComplete(msg, elm, processSingleVideo.curry(null,{
						text: 'Delete',
						attributes: {
							href: ApplicationPaths.basepath + '/cmf/videos/delete/#{id}',
							'class': 'form_related_item_delete_link'
						}
					}));
				}
			});
			if (u) {
				i.observe('change', u.submit.bind(u));
			}
		}
	});
	
	f('input.single_image_ajax_upload_new').each(function(i){
		i = $(i);
		if( i ){
			var action = i.readAttribute('value');
			action = action?action:i.readAttribute('title');
			action = action?action:getBasePath() + '/cmf/fileupload/doupload/';
			var u = new PSWrap.AjaxUpload(i, {
				action: action,
				onComplete: function(msg, elm){
					ajaxUploadOnComplete(msg, elm, processSingleImage.curry({
						text: 'Edit',
						attributes: {
							href: ApplicationPaths.basepath + '/cmf/images/editajax/#{id}',
							'class': 'form_related_item_edit_link'
						}
					},{
						text: 'Delete',
						attributes: {
							href: ApplicationPaths.basepath + '/cmf/images/delete/#{id}',
							'class': 'form_related_item_delete_link'
						}
					}));
				}
			});
			if (u) {
				i.observe('change', u.submit.bind(u));
			}
		}
	});
	f('input.single_document_ajax_upload_new').each(function(i){
		i = $(i);
		if( i ){
			var action = i.readAttribute('value');
			action = action?action:i.readAttribute('title');
			action = action?action:getBasePath() + '/cmf/fileupload/doupload/';
			var u = new PSWrap.AjaxUpload(i, {
				action: action,
				onComplete: function(msg, elm){
					ajaxUploadOnComplete(msg, elm, processSingleDocument.curry({
						text: 'Edit',
						attributes: {
							href: ApplicationPaths.basepath + '/cmf/documents/editajax/#{id}',
							'class': 'form_related_item_edit_link'
						}
					},{
						text: 'Delete',
						attributes: {
							href: ApplicationPaths.basepath + '/cmf/documents/delete/#{id}',
							'class': 'form_related_item_delete_link'
						}
					}));
				}
			});
			if (u) {
				i.observe('change', u.submit.bind(u));
			}
		}
	});
}

Event.observe(window, 'load', function(e){
	initializeFormControls();
});

function getEditDeleteLink( params ){
	attributes = Object.extend({
		/* defaults */
	}, params.attributes || {});
	var link = new Element('a', attributes);
	link.update(params.text || 'Click Here');
	return link;
}

function processSingleItem(view, edit, del, r, elm){
	var id = elm.identify();
	var last_index = id.lastIndexOf('_');
	last_index = last_index == -1?id.length:last_index;
	var elm_id = id.substr( 0, last_index);
	var elm = $(elm_id);
	if( elm ){
		var edit_link = null;
		var delete_link = null;
		var attributes = $H(view.attributes||{});
		view.tag_name = view.tag_name || 'div';
		if( elm.tagName.toLowerCase() != view.tag_name.toLowerCase()){
			var original_element = elm;
			var container = new Element('div', {'class': (view.container_class || 'form_related_item')});
			var attr = {};
			var l = elm.attributes.length;
			var skip_attributes = view.skip_attributes || [];
			for( i=0; i<l; i++){
				if( skip_attributes.indexOf(elm.attributes[i].name) == -1){
					attr[elm.attributes[i].name] = elm.attributes[i].value;
				}
			}
			attributes.each(function(p){
				attr[p.key] = p.value.replace('#{path}', r[2]).replace('#{id}', r[1]);
			});
			var nelm = new Element(view.tag_name, attr);
			if( view.content ){
				nelm.update(view.content.replace('#{path}', r[2]).replace('#{id}', r[1]));
			}
			container.insert(nelm);
			elm.replace(container);
			elm = nelm;
			var next = elm;
			
			if( edit && edit != null ){
				edit.attributes.href = edit.attributes.href?edit.attributes.href.replace('#{id}', r[1]):'';
				edit_link = getEditDeleteLink(edit, r[1], r[2]);
				next.insert({after: edit_link});
				next = edit_link;
			}
			if( del && del != null){
				del.attributes.href = del.attributes.href?del.attributes.href.replace('#{id}', r[1]):'';
				delete_link = getEditDeleteLink(del, r[1], r[2]);
				next.insert({after: delete_link});
			}
			processFormRelatedItem.defer(container, original_element);
		}else{
			attributes.each(function(p){
				elm.writeAttribute(p.key, p.value.replace('#{path}', r[2]).replace('#{id}', r[1]));
			});
			if( view.content ){
				elm.update(view.content.replace('#{path}', r[2]).replace('#{id}', r[1]));
			}
			var div = elm.up('div.form_related_item');
			if( edit ){
				edit_link = div.down('a.form_related_item_edit_link');
				if (edit_link) {
					edit_link.writeAttribute('href', (edit.attributes.href ? edit.attributes.href.replace('#{id}', r[1]) : ''));
				}
			}
			if( del ){
				delete_link = div.down('a.form_related_item_delete_link');
				if (delete_link) {
					delete_link.writeAttribute('href', (del.attributes.href ? del.attributes.href.replace('#{id}', r[1]) : ''));
				}
			}
		}
	}
}
function processSingleDocument(edit, del, r, elm){
	processSingleItem({
		tag_name: 'a',
		attributes: {'href': '#{path}', 'target': '_blank'},
		skip_attributes: ['type'],
		content: '#{path}'
	},
	edit, del, r, elm);
}
function processSingleImage(edit, del, r, elm){
	processSingleItem({
		tag_name: 'img',
		attributes: {'src': '#{path}'},
		skip_attributes: ['type']
	}, 
	edit, del, r, elm);
}

function processSingleVideo(edit, del, r, elm){
	processSingleItem({
		tag_name: 'a',
		attributes: {'href': ApplicationPaths.flash_video_player + '?video=#{path}', 'target': '_blank'},
		skip_attributes: ['type'],
		content: '#{path}'
	},
	edit, del, r, elm);
}

function ajaxUploadOnComplete(msg, elm, processFunction){
	if (msg.indexOf(':') != -1) {
		var r = msg.split(':');
		var response_code = parseInt(r[0]);
		var msg_id = elm.identify() + '_message';
		var msg = $(msg_id);
		if ( response_code != 0) {
			if( msg ){
				msg.hide();
			}
			var id = elm.identify();
			if( response_code == 2){
				// need to create a hidden input to keep track of the ids to insert into the relational table at save time
				var hidden_input_id = 'new_' + id;
				var hidden_input = $(hidden_input_id);
				if( !hidden_input ){
					hidden_input = new Element('input', {type: 'hidden', name: hidden_input_id, id: hidden_input_id, value: r[1] + '=>' + r[2]});
					elm.insert({
						before: hidden_input
					});
				}else{
					hidden_input.value = hidden_input.value + ';' + r[1] + '=>' + r[2];
				}
			}
			if (processFunction && Object.isFunction(processFunction)) {
				processFunction(r, elm);
			}
			elm.clear();
		}else{
			if( !msg ){
				msg = new Element('div', {'class': 'upload_error_message', 'id': msg_id, 'onclick': '$(this).remove();'});
				elm.insert({before: msg});
			}
			msg.update(r[1]);
			msg.show();
		}
	}
}

function createImageListSortableInit( e ){
	createImageListSortable( null, null, e.getSelectedContainer());
}

function createImageListSortable( elm, val, container ){
	elm = $(container);
	if( elm ){
		Sortable.create( elm.identify(), {
			overlap: 'vertical',
			scroll: elm.identify(),
			tag: 'img',
			constraint: null,
			onUpdate: serializeSortableToInput
		});
		serializeSortableToInput(elm);
	}
}

function serializeSortableToInput( container ){
	var id = container.identify();
	var input_id = id + '_order';
	var input = $(input_id);
	if( !input ){
		input = new Element('input', {'type': 'hidden', 'name': input_id, 'id': input_id});
		container.insert({'after': input});
	}
	input.value = Sortable.serialize(id, {'name': input_id});
	//console.log(input.value);
}

function createEditDeleteBuckets( e ){
	var id = e.identify();
	var c = $(id);
	if( c ){
		var l = e.getOptionsItems().length;
		var bc = new Element('div', {'class': 'image_action_buckets', 'id': id + '_action_buckets'});
		if( l == 0 ){
			bc.setStyle({'display': 'none'});
		}
		var edit = new Element('div', {'class': 'edit_bucket'}).update('<p>Drop images here to edit the title, caption, and credit.</p><div class="loading" style="display: none;">&nbsp;</div>');
		var del = new Element('div', {'class': 'delete_bucket'}).update('<p>Drop images here to delete them.</p>');
		var clear = new Element('div', {'class': 'clear_both'});
		
		bc.insert(edit);
		bc.insert(del);
		bc.insert(clear);
		c.next().insert(bc);
		
		Droppables.add(del, {
			containment: e.getOptionsContainer().identify(), 
			onDrop: deleteImage
		});
		
		Droppables.add(edit, {
			containment: e.getOptionsContainer().identify(),
			onDrop: createEditForm
		});
	}
}

function getBasePath(){
	return ((ApplicationPaths && ApplicationPaths.basepath)?ApplicationPaths.basepath:'');
}

function deleteImage( elm ){
	if (confirm('Are you sure you want to delete this item?')) {
		var base_path = (ApplicationPaths && ApplicationPaths.basepath) ? ApplicationPaths.basepath : '';
		
		/* make ajax call to delete image based on the id */
		/* remove image from all drag drop instances */
		var db_id = elm.identify().split('_').last();
		new Ajax.Request(base_path + '/cmf/images/delete/' + db_id + '/1', {
			method: 'post',
			onComplete: function(r){
			//console.log('completed! ' + r.responseText);
			}
		});
		image_selection_lists.invoke('removeElement', elm);
	}
}

function deleteDocument( value ){
	var base_path = (ApplicationPaths && ApplicationPaths.basepath)?ApplicationPaths.basepath:'';
	//console.log('requesting: ' + base_path + '/cmf/documents/delete/' + value + '/1' );
	new Ajax.Request(base_path + '/cmf/documents/delete/' + value + '/1', {
		method: 'post',
		onComplete: function(r){
			//console.log('complete: ' + r.responseText);
		}
	});
	var items = PSWrap.FormControls.SingleContainerMultiselects.items();
	items.invoke('removeOption', value);
}

function prepareEditForm( c, callback){
	initializeFormControls(c);
	var f = c.down('form');
	if( f ){
		var s = f.select('input[type=submit]');
		var l = s.length;
		for( var i=0; i<l; i++){
			if( s[i].value.toLowerCase() == 'save'){
				s[i].observe('click', submitEditForm.bindAsEventListener(c, callback));
			}else if( s[i].value.toLowerCase() == 'cancel'){
				//s[i].observe('click', destroyEditForm.bindAsEventListener(c));
				s[i].observe('click', cancelEditForm.bindAsEventListener(c));
			}
		}
		c.show();
	}
	
}

function submitEditForm( e, callback){
	e.stop();
	var f = this.down('form');
	values = f.serialize();
	f.disable();
	new Ajax.Request( f.action, {
		'method': f.method, 
		'parameters': values,
		'onComplete': function(r){
			var success = r.responseText.split(':')[0];
			if( success == '1'){
				Effect.Fade(this, {'afterFinish': function(e){e.element.remove();}});
				if( Object.isFunction(callback) ){
					callback(r.responseText);
				}
			}else{
				this.update(r.responseText);
				prepareEditForm.defer(this);	
			}
		}.bind(this)
	});
}

function cancelEditForm( e ){
	e.stop();
	var f = this.down('form');
	values = f.serialize();
	values += '&cancel=1';
	f.disable();
	new Ajax.Request( f.action, {
		'method': f.method, 
		'parameters': values,
		'onComplete': function(r){
			Effect.Fade(this, {'afterFinish': function(e){e.element.remove()}});
		}.bind(this)
	});
}

function destroyEditForm( e ){
	e.stop();
	Effect.Fade(this, {'afterFinish': function(e){e.element.remove()}});
}

function createEditForm(elm, trigger, event, url, callback){
	var base_path = (ApplicationPaths && ApplicationPaths.basepath) ? ApplicationPaths.basepath : '';
	var displays = showLoading(trigger);
	if (elm) {
		var db_id = elm.identify().split('_').last();
	}
	url = url || base_path + '/cmf/images/editajax/' + db_id;
	//url = url || base_path + '/cmf/screenshots/editajax/' + db_id;
	
	var c = new Element('div', {'class': 'edit_form_container'});
	var offset = trigger.cumulativeOffset();
	c.setStyle({'display': 'none', 'position': 'absolute', 'top': offset.top + 'px', 'left': offset.left + 'px'});
	$$('body')[0].insert(c);
	new Ajax.Request(url, {
		onComplete: function(r){
			c.update(r.responseText);
			prepareEditForm.defer(c, callback);
			hideLoading(trigger, displays);
		}
	});
}

function createEditFormFromLink(a){
	var displays = showLoading(a);
	url = a.readAttribute('href');
	if( url ){
		var c = new Element('div', {'class': 'edit_form_container'});
		var offset = trigger.cumulativeOffset();
		c.setStyle({'display': 'none', 'position': 'absolute', 'top': offset.top + 'px', 'left': offset.left + 'px'});
		$$('body')[0].insert(c);
		new Ajax.Request(url, {
			onComplete: function(r){
				c.update(r.responseText);
				prepareEditForm.defer(c);
				hideLoading(a, displays);
			}
		});
	}
}

function showLoading(elm){
	var loads = elm.select('.loading');
	if( loads.length > 0 ){
		var display_vals = $H();
		elm.childElements().each( function(e){
			display_vals.set(e, e.getStyle('display'));
			e.hide();
		});
		loads.invoke('show');
		return display_vals;
	}
}

function hideLoading(elm, displays){
	//console.log(displays);
	var loads = elm.select('.loading');
	elm.childElements().each( function(e){
		var d = displays.get(e);
		if( d ){
			e.setStyle({'display': d});
		}
	});
	loads.invoke('hide');
}

function toggleEditDeleteBuckets( elm, val, container){
	var id = container.identify();
	id = id.substring(0, id.lastIndexOf('_')) + '_action_buckets';
	//console.log(id);
	var ab = $(id);
	if( ab ){
		if( container.childNodes.length > 0){
			ab.show();
		}else{
			ab.hide();
		}
	}
}
